﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using OnlinePlots.Plots.Elements;
using OnlinePlots.Plots.DataSets;
using System.Globalization;
using System.Windows.Browser;
using MathCompiler.Expressions;
using MathCompiler.Tools;
using System.Collections.Generic;
using MathCompiler.Exceptions;

namespace OnlinePlotsService
{
    public delegate void MathCompilerExceptionRaisedEventHandler(object sender, Exception e);

    public class FunctionItem
    {
        private String _function;
        private ExplicitFunctionPlotItem _plotItem;

        public event EventHandler VisibilityChanged;
        public event MathCompilerExceptionRaisedEventHandler MathCompilerExceptionRaised;

        public Color Color
        {
            get { return ((SolidColorBrush)_plotItem.PlotLine.Brush).Color; }
            set { ((SolidColorBrush)_plotItem.PlotLine.Brush).Color = value; }
        }

        [System.Xml.Serialization.XmlIgnoreAttribute]
        public Brush Brush
        {
            get
            {
                return _plotItem.PlotLine.Brush;
            }
        }

        public String Name
        {
            get { return _plotItem.Name; }
            set { _plotItem.Name = value; }
        }

        public String Function
        {
            get { return _function; }
            set
            {
                _function = value;

                ContinousPlotDataSet ds = _plotItem.DataSet as ContinousPlotDataSet;

                string f = _function.ToLower().Replace(" ", "");
                PreparedExpression pe = MathCompiler.ToolsHelper.Parser.Parse(f);
                CompiledExpression ce = MathCompiler.ToolsHelper.Optimizer.Optimize(MathCompiler.ToolsHelper.Compiler.Compile(pe));

                List<VariableValue> variables = new List<VariableValue>();
                VariableValue arg = new VariableValue(0, "x");
                variables.Add(arg);
                variables.Add(new VariableValue(Math.E, "e"));
                variables.Add(new VariableValue(Math.PI, "pi"));

                ds.Function = x =>
                {
                    try
                    {
                        arg.Value = x;
                        return MathCompiler.ToolsHelper.Calculator.Calculate(ce, variables);
                    }
                    catch (MathProcessorException e)
                    {
                        if (MathCompilerExceptionRaised != null) MathCompilerExceptionRaised(this, e);

                        ds.Function = _x => { return 0; };
                        return 0;
                    }
                };
            }
        }

        public Boolean Visibility
        {
            get { return _plotItem.Visible; }
            set
            {
                _plotItem.Visible = value;
                if (VisibilityChanged != null) VisibilityChanged(this, EventArgs.Empty);
            }
        }

        [System.Xml.Serialization.XmlIgnoreAttribute]
        public ExplicitFunctionPlotItem PlotItem
        {
            get
            {
                return _plotItem;
            }
        }

        public FunctionItem()
        {
            _plotItem = new ExplicitFunctionPlotItem();
            _plotItem.PlotLine.Brush = new SolidColorBrush(Colors.Blue);
            _plotItem.DataSet = new ContinousPlotDataSet(x => { return 0; });

            Function = "0";
        }
    }
}
